﻿using System;
using System.Collections.Generic;
using FastNet.BusinessSystem.Exceptions;
using FastNet.RepositorySystem;
using SampleBusiness.Objects;

namespace SampleUI
{
    internal static class ContactManagement
    {
        public static void Run()
        {
            while (true)
            {
                Console.Clear();
                Console.ForegroundColor = ConsoleColor.White;

                Console.WriteLine("Please select an option:");
                Console.WriteLine();
                Console.WriteLine("0) Main Menu");
                Console.WriteLine();
                Console.WriteLine("1) Add New Contact");
                Console.WriteLine("2) Show Contact Details");
                Console.WriteLine("3) Delete Contact");
                Console.WriteLine("4) Show Contact Details by Shipping Address");
                Console.WriteLine("5) List all Contacts");
                Console.WriteLine();

                switch (Console.ReadKey().KeyChar)
                {
                    case '1':
                        AddContact();
                        break;
                    case '2':
                        RetrieveContactId();
                        break;
                    case '3':
                        DeleteContactId();
                        break;
                    case '4':
                        RetrieveContactShippingId();
                        break;
                    case '5':
                        RetrieveAllContacts();
                        break;
                    case '0':
                        return;
                }
                Console.WriteLine("");
            }
        }

        private static void AddContact()
        {
            Console.Clear();
            Common.WriteTitle("Add Contact");
            Console.WriteLine("Please enter the details of the new contact:");

            Contact contact = SampleBusiness.SampleBusinessFactory.ContactManager.Create();
            bool firstTime = true;

            while (firstTime || !contact.IsValid)
            {
                Console.WriteLine();
                if (firstTime || !string.IsNullOrEmpty(contact["FirstName"]))
                {
                    if (!firstTime)
                        Common.WriteError("* The following errors were found: \n\n {0}", contact["FirstName"]);

                    Console.Write("First Name: ");
                    contact.FirstName = Console.ReadLine();
                }

                if (firstTime || !string.IsNullOrEmpty(contact["LastName"]))
                {
                    if (!firstTime)
                        Common.WriteError("* The following errors were found: \n\n {0}", contact["LastName"]);

                    Console.Write("Last Name: ");
                    contact.LastName = Console.ReadLine();
                }

                if (firstTime || !string.IsNullOrEmpty(contact["Phone"]))
                {
                    if (!firstTime)
                        Common.WriteError("* The following errors were found: \n\n {0}", contact["Phone"]);

                    Console.Write("Phone Number: ");
                    contact.Phone = Console.ReadLine();
                }

                if (firstTime || !string.IsNullOrEmpty(contact["Email"]))
                {
                    if (!firstTime)
                        Common.WriteError("* The following errors were found: \n\n {0}", contact["Email"]);

                    Console.Write("Email Address: ");
                    contact.Email = Console.ReadLine();
                }
                //*************************************************************************
                Guid tempGuid;
                if (firstTime || !string.IsNullOrEmpty(contact["ShippingAddressId"]))
                {
                    if (!firstTime)
                        Common.WriteError("* The following errors were found: \n\n {0}", contact["ShippingAddressId"]);

                    Console.Write("Shipping Address Id: ");
                    if (Guid.TryParse(Console.ReadLine(), out tempGuid))
                        contact.ShippingAddressId = new Identity(tempGuid);
                }
                if (firstTime || !string.IsNullOrEmpty(contact["BillingAddressId"]))
                {
                    if (!firstTime)
                        Common.WriteError("* The following errors were found: \n\n {0}", contact["BillingAddressId"]);

                    Console.Write("Billing Address Id: ");
                    if (Guid.TryParse(Console.ReadLine(), out tempGuid))
                        contact.BillingAddressId = new Identity(tempGuid);
                }
                //****************************************************************************
                firstTime = false;
            }

            try
            {
                if (contact.CanSave)
                    contact.SaveChanges();
                Common.WriteSuccess("Contact has been saved. You can refer to contact ID: \n\t{0}", contact.Id);
            }
            catch (BusinessSaveException ex)
            {
                Common.WriteError("There was an error saving the new contact to the database: \n\t{0}", ex.Message);
            }

            Common.WaitForAnyKey();
        }

        private static void RetrieveContactId()
        {
            Console.Clear();
            Common.WriteTitle("Retrieve Contact");

            Contact contact;
            while (true)
            {
                Console.Write("Please enter the ID of the contact: ");
                string contactId = Console.ReadLine();
                if (string.IsNullOrEmpty(contactId))
                {
                    Common.WriteError("There was no value entered. Please try again.");
                    continue;
                }

                long id;
                if (!Int64.TryParse(contactId, out id))
                {
                    Common.WriteError("Value was not of the correct type. Number expected.");
                    continue;
                }

                try
                {
                    contact = SampleBusiness.SampleBusinessFactory.ContactManager.Retrieve(id);
                    break;
                }
                catch (BusinessRetrieveException ex)
                {
                    Common.WriteError("Unable to retrieve Contact: \n\t{0}", ex.Message);
                }
            }

            PrintContact(contact);

            Common.WaitForAnyKey();
        }

        private static void DeleteContactId()
        {
            Console.Clear();
            Common.WriteTitle("Delete Contact");

            Contact contact;

            while (true)
            {
                Console.Write("Please enter the ID of the contact: ");

                string contactId = Console.ReadLine();
                if (string.IsNullOrEmpty(contactId))
                {
                    Common.WriteError("There was no value entered. Please try again.");
                    continue;
                }

                long id;
                if (!Int64.TryParse(contactId, out id))
                {
                    Common.WriteError("Value was not of the correct type. Number expected.");
                    continue;
                }

                try
                {
                    contact = SampleBusiness.SampleBusinessFactory.ContactManager.Retrieve(id);

                    if (contact != null)
                        break;

                    Common.WriteError("Contact not found");
                }
                catch (BusinessRetrieveException ex)
                {
                    Common.WriteError("Unable to retrieve Contact: \n\t{0}", ex.Message);
                }
            }

            try
            {
                contact.Delete();
                Common.WriteSuccess("Contact has been deleted.");
            }
            catch (BusinessDeleteException ex)
            {
                Common.WriteError("Unable to delete Contact: \n\t{0}", ex.Message);
            }

            Common.WaitForAnyKey();
        }

        private static void RetrieveContactShippingId()
        {
            Console.Clear();
            Common.WriteTitle("Retrieve Contact By Shipping Address");

            Contact contact;
            while (true)
            {
                Console.Write("Please enter the ID of the address: ");
                string addressId = Console.ReadLine();
                if (string.IsNullOrEmpty(addressId))
                {
                    Common.WriteError("There was no value entered. Please try again.");
                    continue;
                }

                Guid id;
                if (!Guid.TryParse(addressId, out id))
                {
                    Common.WriteError("Value was not of the correct type. Guid expected.");
                    continue;
                }

                try
                {
                    contact = SampleBusiness.SampleBusinessFactory.ContactManager.RetreiveByShippingAddressId(id);
                    break;
                }
                catch (BusinessRetrieveException ex)
                {
                    Common.WriteError("Unable to retrieve Contact: \n\t{0}", ex.Message);
                }
            }

            PrintContact(contact);

            Common.WaitForAnyKey();
        }

        private static void RetrieveAllContacts()
        {
            Console.Clear();
            Common.WriteTitle("Retrieve All Contacts");

            IList<Contact> contacts = SampleBusiness.SampleBusinessFactory.ContactManager.Retrieve();

            foreach (Contact contact in contacts)
                PrintContact(contact);

            Common.WaitForAnyKey();
        }

        private static void PrintContact(Contact contact)
        {
            Console.WriteLine();
            Console.WriteLine("        ID: {0}", contact.Id);
            Console.WriteLine("First Name: {0}", contact.FirstName);
            Console.WriteLine(" Last Name: {0}", contact.LastName);
            Console.WriteLine("     Email: {0}", contact.Email);
            Console.WriteLine("     Phone: {0}", contact.Phone);
            Console.WriteLine("  Shipping: {0}", contact.ShippingAddressId);
            Console.WriteLine("   Billing: {0}", contact.BillingAddressId);
        }
    }
}
